<template>
  <i v-if="shape || shape2" :class="'ee-shape' + (isInShape ? '' : ' iconfont ' + current)" @click="off = !off">
    <template v-if="isInShape">
      <div :class="current">
        <i></i>
        <i></i>
        <i></i>
      </div>
    </template><template v-else />
    <slot></slot>
  </i><template v-else />
</template>

<script type="text/javascript">
/** 预设的形状枚举
 * @typedef {keyof shapes} shape
 */
export const shapes = {
  /** 设置(三横) */
  "setting": "setting",
  /** 关闭(叉叉) */
  "close": "close",
  /** 加号 */
  "add": "add",
  /** 减号 */
  "minus": "minus",
  /** 打勾 */
  "tick": "tick",
  /** 更多(···) */
  "more": "more",
  /** 上箭头 */
  "up": "up",
  /** 右箭头 */
  "right": "right",
  /** 下箭头 */
  "down": "down",
  /** 左箭头 */
  "left": "left",
  /** 搜索(放大镜) */
  "search": "search",
  /** 刷新/重置 */
  "reset": "reset",
  /** 眼睛(密码) */
  "eye": "eye",
  /** 眼睛加斜杠(密码不给看) */
  "eye-close": "eye-close",
  /** 闭眼睛(密码不给看) */
  "eye-close2": "eye-close2",
  /** 导入/上传 */
  "import": "import",
  /** 导出/下载 */
  "export": "export",
};

/** 使用 DOM 元素制作的简单形状，不同形状间可以变形
 * 
 * 若设置的形状不在预设的形状枚举中，则视为 iconfont 图标的 class 名
 */
export default {
  name: "ee-shape",
  emits: {
    /** 形状切换时触发
     * @param {boolean} isShape2 - true: 形状2 / false: 形状1
     */
    change: (isShape2) => true,
  },
  slots: {
    /** 在图标后面 */
    default: {}
  },
  data() {
    return {
      off: false,
    }
  },
  props: {
    /** 控制形状变化，默认不设置则点击形状会切换形状
     * 
     * @example
     * 非 undefined 可以父组件自己控制形状的变化
     * <ee-shape :on="mySwitch">
     * 
     * @example
     * 或者可以禁止点击切换形状，自己控制shape的变化
     * <ee-shape on :shape="shape">
     */
    on: {},
    /** 形状 1
     * @type {shape}
     */
    shape: String,
    /** 形状 1 */
    // shape: {
    //   type: String,
    //   /** @type {shape} */
    //   default: undefined,
    // },
    /** 形状 2 */
    shape2: {
      type: String,
      /** @type {shape} */
      default: undefined,
    },
  },
  computed: {
    current() {
      return this.isShape2 ? this.shape2 : this.shape;
    },
    isInShape() {
      return this.inShapes(this.current);
    },
    isShape2() {
      return !!(this.on === undefined ? (this.off && this.shape2) : (this.on || this.on != ''));
    }
  },
  methods: {
    inShapes(s) {
      return s && shapes[s];
    }
  },
  watch: {
    isShape2(value) {
      this.$emit('change', value);
    }
  },
  mounted() {
    this.$emit('change', this.isShape2);
  }
}
</script>

<style lang="scss">
.ee-shape {
  cursor: pointer;
  display: inline-flex;
  align-items: center;
  // bug: 没有这个vertical-align: bottom会导致内容48px，容器却有56px，可能是inline-block的问题
  vertical-align: bottom;
  flex: none;
  box-sizing: content-box;
  font-style: normal;
  line-height: 1;

  &>div {
    width: 1em;
    height: 1em;

    &>i {
      transition-property: transform, width, height, border, margin, background-color, color, opacity;
      transition-duration: var(--ee-transition-duration);
      background-color: currentColor;
      display: block;
      width: 100%;
      height: .125em;
      margin: .15625em 0;
    }

    &.close {
      :nth-child(1) {
        transform: translateY(0.28125em) rotateZ(45deg);
      }

      :nth-child(2) {
        opacity: 0;
      }

      :nth-child(3) {
        transform: translateY(-0.28125em) rotateZ(-45deg);
      }
    }

    &.add {
      :nth-child(1) {
        transform: translateY(0.28125em) rotate(90deg);
      }

      :nth-child(2) {
        opacity: 0;
      }

      :nth-child(3) {
        transform: translateY(-0.28125em);
      }
    }

    &.minus {
      i {
        opacity: 0;
      }

      :nth-child(1) {
        opacity: 1;
        transform: translateY(0.28125em)
      }
    }

    &.tick {
      :nth-child(1) {
        width: 40%;
        transform: translate(0.02em, 0.41em) rotate(45deg);
      }

      :nth-child(2) {
        opacity: 0;
      }

      :nth-child(3) {
        width: 80%;
        transform: translate(0.2em, -0.25em) rotate(-45deg);
      }
    }

    &.more {
      i {
        width: .125em;
        border-radius: 50%;
        margin: .15625em auto;
      }

      :nth-child(1) {
        transform: translate(-0.28125em, 0.28125em);
      }

      :nth-child(3) {
        transform: translate(0.28125em, -0.28125em);
      }
    }

    &.up {
      i {
        width: 60%;
      }

      :nth-child(1) {
        transform: translate(59%, .25em) rotateZ(45deg);
      }

      :nth-child(2) {
        opacity: 0;
      }

      :nth-child(3) {
        transform: translate(0%, -0.3em) rotateZ(-45deg);
      }
    }

    &.right {
      i {
        width: 60%;
      }

      :nth-child(1) {
        transform: translate(40%, .1em) rotateZ(45deg);
      }

      :nth-child(2) {
        opacity: 0;
      }

      :nth-child(3) {
        transform: translate(40%, -.1em) rotateZ(-45deg);
      }
    }

    &.down {
      i {
        width: 60%;
      }

      :nth-child(1) {
        transform: translate(59%, .25em) rotateZ(-45deg);
      }

      :nth-child(2) {
        opacity: 0;
      }

      :nth-child(3) {
        transform: translate(0%, -0.3em) rotateZ(45deg);
      }
    }

    &.left {
      i {
        width: 60%;
      }

      :nth-child(1) {
        transform: translate(25%, .1em) rotateZ(-45deg);
      }

      :nth-child(2) {
        opacity: 0;
      }

      :nth-child(3) {
        transform: translate(25%, -.1em) rotateZ(45deg);
      }
    }

    &.search {
      :nth-child(1) {
        transform: translateY(-0.15em);
        width: 90%;
        height: 90%;
        background-color: transparent;
        border-color: currentColor;
        border-radius: 50%;
        border: solid 0.125em;
        box-sizing: border-box;
      }

      :nth-child(2) {
        opacity: 0;
        margin-top: -75%;
      }

      :nth-child(3) {
        transform: translate(0.7em) rotateZ(45deg);
        width: 30%;
      }
    }

    &.reset {
      :nth-child(1) {
        transform: translateY(-0.155em);
        height: 100%;
        background-color: transparent;
        border-color: currentColor;
        border-radius: 50%;
        border: solid 0.125em;
        box-sizing: border-box;
        clip-path: polygon(0% 0%, 100% 0%, 100% 20%, 50% 50%, 100% 80%, 100% 101%, 0% 101%);
      }

      :nth-child(2) {
        opacity: 0;
        margin-top: -85%;
      }

      :nth-child(3) {
        transform: translate(.725em, -.525em) rotate(-45deg);
        width: 0;
        height: 0;
        border: 0.2em solid currentColor;
        border-bottom: none;
        border-left-color: transparent;
        border-right-color: transparent;
        background-color: transparent;
      }
    }

    &.eye,
    &.eye-close,
    &.eye-close2 {

      :nth-child(1),
      :nth-child(2) {
        background-color: transparent;
        border-color: currentColor;
        border-radius: 50%;
        box-sizing: border-box;
      }

      :nth-child(1) {
        width: 100%;
        height: 80%;
        border: solid 0.02em;
        border-top-width: .1em;
        border-bottom-width: .1em;
        margin: 10% 0;
      }

      :nth-child(2) {
        width: 50%;
        height: 50%;
        margin: auto;
        border: 0.1em solid;
        margin-top: -75%;
      }

      :nth-child(3) {
        opacity: 0;
        transform: rotate(-45deg);
        margin-top: -30%;
        width: 110%;
        margin-left: -5%;
      }
    }

    &.eye-close {
      :nth-child(3) {
        opacity: 1;
      }
    }

    &.eye-close2 {
      :nth-child(1) {
        border: none;
        border-bottom: solid .1em;
      }

      :nth-child(2),
      :nth-child(3) {
        opacity: 0;
      }
    }

    &.import,
    &.export {
      :nth-child(1) {
        width: 0.7em;
      }

      :nth-child(2) {
        width: 0;
        height: 0;
        border: .5em solid currentColor;
        border-left-color: transparent;
        border-right-color: transparent;
        background-color: transparent;
      }

      :nth-child(3) {
        height: .5em;
        background-color: transparent;
        border: max(.125em, 2px) solid currentColor;
        border-top: none;
        transform: translateY(-.6em);
      }
    }

    &.import {
      :nth-child(1) {
        transform: rotate(90deg) translate(0.15em, -0.15em);
      }

      :nth-child(2) {
        border-bottom: none;
        transform: scale(.55);
      }
    }

    &.export {
      :nth-child(1) {
        transform: rotate(90deg) translate(0.2em, -0.15em);
      }

      :nth-child(2) {
        border-top: none;
        transform: translate(0, -.55em) scale(0.55);
      }
    }
  }
}
</style>